﻿using System.Collections.Generic;
using System.Data;
using System.Linq;
using System.Xml.Linq;
using System.Xml.XPath;
using PengSW.NotifyPropertyChanged;
using PengSW.XmlHelper;
using static PengSW.XmlHelper.XmlLinqHelper;

namespace PengSW.XmlImport
{
    public class FieldDefine : NotifyPropertyChangedObject, IXmlSeriable
    {
        public FieldDefine(RecordDefine aRecordDefine)
        {
            RecordDefine = aRecordDefine;
        }

        public RecordDefine RecordDefine { get; }

        public string SourceField { get { return _SourceField; } set { SetValue(ref _SourceField, value, nameof(SourceField), nameof(FieldName)); } }
        private string _SourceField;

        public string TargetField { get { return _TargetField; } set { SetValue(ref _TargetField, value, nameof(TargetField), nameof(FieldName)); } }
        private string _TargetField;

        public string FieldName => string.IsNullOrWhiteSpace(TargetField) ? SourceField : TargetField;
        public bool IsValid => !string.IsNullOrWhiteSpace(FieldName);

        public string FieldXPath { get { return _FieldXPath; } set { SetValue(ref _FieldXPath, value, nameof(FieldXPath)); } }
        private string _FieldXPath;

        public string DataType { get { return _DataType; } set { SetValue(ref _DataType, value, nameof(DataType)); } }
        private string _DataType = "String";

        public string[] DataTypes => _DataTypes;
        private static string[] _DataTypes = new string[] { "String", "Bool", "Integer", "Double", "File" };

        public ReplaceRule Replace { get { return _Replace; } set { SetValue(ref _Replace, value, nameof(Replace)); } }
        private ReplaceRule _Replace;

        public void CreateField(DataTable aDataTable)
        {
            if (!IsValid) return;
            if (aDataTable.Columns.Contains(FieldName)) return;
            aDataTable.Columns.Add(new DataColumn(FieldName));
        }

        /// <summary>
        /// 从指定记录节中提取相应字段值，并填入指定数据行的对应字段中。
        /// </summary>
        /// <param name="aDataRow">目标数据行</param>
        /// <param name="aRecordXElement">源记录节</param>
        public void Import(DataRow aDataRow, XElement aRecordXElement)
        {
            if (!IsValid) return;
            string aFieldValue;
            // TODO: 如何从节属性中提取字段值？
            if (string.IsNullOrWhiteSpace(FieldXPath))
                aFieldValue = aRecordXElement.Element(SourceField)?.Value;
            else
                aFieldValue = aRecordXElement.XPathSelectElement(FieldXPath)?.Value;
            if (Replace != null)
            {
                aFieldValue = Replace.Replace(aFieldValue);
            }
            // 假设数据表中的字段已经准备好，不再检查字段是否存在。
            aDataRow[FieldName] = aFieldValue;
        }

        public XElement CreateXElement(string aXmlNodeName)
        {
            return new XElement(aXmlNodeName,
                CreateXAttribute(nameof(SourceField), SourceField),
                CreateXAttribute(nameof(TargetField), TargetField),
                CreateXAttribute(nameof(FieldXPath), FieldXPath),
                CreateXAttribute(nameof(DataType), DataType),
                CreateXAttribute("ReplaceId", Replace?.Id));
        }

        public void ReadFromXml(XElement aXElement)
        {
            if (aXElement == null) return;
            SourceField = aXElement.GetAttributeValue(nameof(SourceField), null);
            TargetField = aXElement.GetAttributeValue(nameof(TargetField), null);
            FieldXPath = aXElement.GetAttributeValue(nameof(FieldXPath), null);
            DataType = aXElement.GetAttributeValue(nameof(DataType), "String");
            string aReplaceId = aXElement.GetAttributeValue("ReplaceId", null);
            Replace = RecordDefine?.TableDefine?.ImportRule?.ReplaceRules?.FirstOrDefault(r => r.Id == aReplaceId);
        }
    }
}
